package com.yanqu.road.web.controller.usercenter.newadmin;

import com.alibaba.fastjson.JSONObject;
import com.yanqu.road.entity.servercenter.ProcessInfo;
import com.yanqu.road.entity.servercenter.ServerInfo;
import com.yanqu.road.entity.web.ICrossWebService;
import com.yanqu.road.server.manger.ServerListMgr;
import com.yanqu.road.utils.config.Config;
import com.yanqu.road.utils.http.HttpHelper;
import com.yanqu.road.utils.string.StringUtils;
import com.yanqu.road.web.WebServer;

import javax.xml.namespace.QName;
import javax.xml.ws.Service;
import java.net.URL;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.*;

public class CenterReloadHelper {

    public static String serverMgrReload(List<ServerInfo> serverInfoList, String mgrClass, int timeOutSecond){

        ExecutorService webExecutor = WebServer.getWebExecutor();

        StringBuilder msg = new StringBuilder();

        Map<String, String> paramMap = new HashMap<>();
        Map<String, String> param = new HashMap<>();
        param.put("name", mgrClass);
        JSONObject param1 = new JSONObject();
        param1.put("param", param);
        paramMap.put("param", param1.toJSONString());

        List<Long> failList = new ArrayList<>();
        List<Long> timeoutList = new ArrayList<>();
        List<Future> futureList = new ArrayList<>();
        for (ServerInfo serverInfo : serverInfoList) {
            if(Config.isDebug() && serverInfo.getServerId() != 99938028L && serverInfo.getServerId() != 99900027L && serverInfo.getServerId() != 99999999L){
                continue;
            }
            Future future = webExecutor.submit(() -> {
                String result = "";
                try {
                    result = HttpHelper.doPost(serverInfo.getWebServerUrl() + "/reloadMgr", paramMap, "UTF-8");
                    JSONObject jsonObject = JSONObject.parseObject(result);
                    if (jsonObject.getIntValue("status") == 0) {
                        ServerListMgr.getLogger().error("error, 区服 {} 刷新 {} 失败", serverInfo.getServerId(), mgrClass);
                        failList.add(serverInfo.getServerId());
                    }
                } catch (Exception ex) {
                    ServerListMgr.getLogger().error("error, 区服 {} 刷新 {} 异常。{} {}", result == null ? "" : result, ex.toString(), serverInfo.getServerId(), mgrClass);
                }
                return true;
            });
            futureList.add(future);
        }
        if(!futureList.isEmpty()) {
            for (int i = 0; i < futureList.size(); i++) {
                Future future = futureList.get(i);
                try {
                    future.get(timeOutSecond, TimeUnit.SECONDS);
                } catch (InterruptedException | ExecutionException | TimeoutException e) {
                    ServerListMgr.getLogger().error("", e);
                    timeoutList.add(serverInfoList.get(i).getServerId());
                }
            }
        }

        msg.append("刷新成功!");
        if(!failList.isEmpty()){
            msg.append("[").append(mgrClass).append("]").append("失败：[").append(StringUtils.listToString(failList, ",")).append("]").append(".");
        }
        if(!timeoutList.isEmpty()){
            msg.append("[").append(mgrClass).append("]").append("超时：[").append(StringUtils.listToString(failList, ",")).append("]").append(".");
        }

        return msg.toString();
    }


    public static String crossServerMgrReload(List<ProcessInfo> processInfoList, String mgrClass, int timeOutSecond){

        ExecutorService webExecutor = WebServer.getWebExecutor();
        List<Long> failList = new ArrayList<>();
        try {
            //遍历异步通知活动跨服
            CountDownLatch countDownLatch = new CountDownLatch(processInfoList.size());
            JSONObject param = new JSONObject();
            param.put("content", mgrClass);
            for (ProcessInfo processInfo : processInfoList) {
                webExecutor.execute(() -> {
                    try {
                        String url = "http://" + processInfo.getAddress() + ":" + processInfo.getAdminPort() + "/crossws?wsdl";
                        QName qName = new QName("http://webservice.server.road.yanqu.com/", "GrossWebServiceService");
                        Service service = Service.create(new URL(url), qName);
                        ICrossWebService crossWebService = service.getPort(ICrossWebService.class);
                        String resp = crossWebService.executeAdminOperate("AgentReload|reloadMgr", param.toJSONString(), "Yanqu123");
                        JSONObject result = JSONObject.parseObject(resp);
                        int status = result.getInteger("status");
                        if (status != 1) {
                            failList.add((long) processInfo.getServerId());
                            ServerListMgr.getLogger().error("刷新 {} {} 超时", processInfo.getServerId(), mgrClass);
                        }
                    } catch (Exception e) {
                        failList.add((long) processInfo.getServerId());
                    } finally {
                        countDownLatch.countDown();
                    }
                });
            }
            //等待
            if (!countDownLatch.await(timeOutSecond, TimeUnit.SECONDS)) {
                ServerListMgr.getLogger().error("刷新超时");
            }
        } catch (Exception e) {
            ServerListMgr.getLogger().error("", e);
        }
        StringBuilder msg = new StringBuilder();
        msg.append("跨服刷新成功!");
        if(!failList.isEmpty()){
            msg.append("[").append(mgrClass).append("]").append("失败：[").append(StringUtils.listToString(failList, ",")).append("]").append(".");
        }

        return msg.toString();
    }

}
